/*
 * cxxomfort example: gcd
 * 
 * This program provides sample usage of the 
 * cxxomfort equivalent to the C++17 gcd() and lcm() functions.
 * 
 * As an added point, this also tests that 
 * CXXO_FOREACH is working correctly.
 * 
 */

#include <cxxomfort/base.hpp>
#include <cxxomfort/numeric.hpp>
#include <cxxomfort/library/numeric.hpp>
#include <cxxomfort/library/type_name.hpp>
#include <numeric>
#include <iostream>
#include <cxxomfort/array.hpp>

namespace cxl= cxxomfort::library;
namespace numeric= cxxomfort::library::numeric;

int main () {
    using namespace std;

    cout<< "gcd, lcm functions: "<< endl;
    const unsigned I= 18, J= 74;
    cout<< "I= "<< I<< " J= "<< J<< endl;
    cout<< "gcd= "<< gcd(I,J)<< endl;
    cout<< "lcm= "<< lcm(I,J)<< endl;
    
    
    cout<< "static_gcd, static_lcm: "<< endl;
    enum { EX=22, EY=33 };
    cout<< "using constant-time integers EX, EY : "<< EX<< ","<< EY<< "."<< endl;
    unsigned X = numeric::ctmath::static_gcd<I,J>::value;
    cout<< "template gcd of I, J: "<< X<< endl;
    unsigned Y = numeric::ctmath::static_gcd<EX,EY>::value;
    cout<< "template gcd of EX, EY: "<< Y<< endl;

    array<int, numeric::ctmath::static_gcd<EX,EY>::value> ai;
    cout<< "std::array with size equal to the gcd above: ";
    cout<< cxxomfort::typeid_demangle(typeid(ai))<< endl;
    // compile-time for C++03
#if (CXXOMFORT_CXX_STD >= 2011)
    cout<< "constexpr gcd, lcm functions:"<< endl;
    constexpr unsigned GX = gcd(I,J); 
    static_assert(2==GX, "gcd");
    cout<< "constexpr, GX: "<< GX<< endl;
#endif
}

